package co.edu.unal.bioingenium.kbmed.knowledge.similarity.vo;

import gnu.trove.map.hash.TObjectFloatHashMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author Luis A Riveros
 */
public class CategoryNeighborSimilarityValues {

    /**
     * The category 
     */
    private String category;
    /**
     * Map<conceptId, TObjectDoubleHashMap<relatedConceptId>>
     */
    private Map<String, TObjectFloatHashMap<String>> similarConceptsValuesMap;
    /**
     * Map<conceptId, List<relatedConceptId>> 
     */
    private Map<String, List<String>> similarConceptsSortedList;

    /**
     * 
     * @param category 
     */
    public CategoryNeighborSimilarityValues(String category) {
        this.category = category;
        similarConceptsValuesMap = new HashMap<String, TObjectFloatHashMap<String>>();
        similarConceptsSortedList = new HashMap<String, List<String>>();

    }

    /**
     * 
     * @return
     */
    public String getCategory() {
        return category;
    }

    /**
     * 
     * @param conceptId 
     * @return
     */
    public TObjectFloatHashMap<String> getSimilarConceptsValuesMap(String conceptId) {
        return similarConceptsValuesMap.get(conceptId);
    }

    /**
     * 
     * @param conceptId
     * @param relatedConceptId
     * @param similarity
     */
    public void putSimilarityValue(String conceptId, String relatedConceptId, float similarity) {
        TObjectFloatHashMap<String> tempMap;
        if ((tempMap = similarConceptsValuesMap.get(conceptId)) != null) {
            tempMap.put(relatedConceptId, similarity);
        } else {
            tempMap = new TObjectFloatHashMap<String>();
            tempMap.put(relatedConceptId, similarity);
            similarConceptsValuesMap.put(conceptId, tempMap);
        }
    }

    /**
     * 
     * @param conceptId
     * @param relatedConceptId
     * @return  
     */
    public float getSimilarityValue(String conceptId, String relatedConceptId) {
        return similarConceptsValuesMap.get(conceptId).get(relatedConceptId);
    }

    /**
     * 
     * @param conceptId 
     * @return
     */
    public List<String> getSimilarConceptsSortedList(String conceptId) {
        List<String> tempList = similarConceptsSortedList.get(conceptId);
        if (tempList == null || tempList.size() != similarConceptsValuesMap.get(conceptId).size()) {
            tempList = new ArrayList<String>();
            tempList.retainAll(similarConceptsValuesMap.get(conceptId).keySet());
            Collections.sort(tempList, new NeighborSimilarityComparator(similarConceptsValuesMap.get(conceptId)));
            similarConceptsSortedList.put(conceptId, tempList);
            return tempList;
        }
        return tempList;
    }

    /**
     * 
     * @param conceptId 
     * @param k 
     * @return
     */
    public List<String> getSimilarConceptsSortedList(String conceptId, int k) {
        return getSimilarConceptsSortedList(conceptId).subList(0, k);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final CategoryNeighborSimilarityValues other = (CategoryNeighborSimilarityValues) obj;
        if ((this.category == null) ? (other.category != null) : !this.category.equals(other.category)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 97 * hash + (this.category != null ? this.category.hashCode() : 0);
        return hash;
    }
}
